package com.sinder.campus_prophet.utils;

import com.sinder.campus_prophet.exception.WxApiException;
import org.json.JSONObject;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriBuilder;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriTemplate;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 封装webClient通用请求框架
 * 调用函数后，需要调用block()请求才会生效并响应信息
 * return T
 * @author sinder
 * Date 2023/3/16/21:38
 **/
@Component
public class WebHttpClient<T> {
    private final WebClient wxApiWebClient;

    public WebHttpClient(@Qualifier("wxApiWebClient") WebClient wxApiWebClient) {
        this.wxApiWebClient = wxApiWebClient;
    }

    /**
     * @param url
     * @param params MultiValueMap一个键可以放多个值
     * @return
     */
    public Mono<T> wxGet(String url, MultiValueMap<String, String> params, Class<T> clazz) {
        return wxApiWebClient.get()
                .uri(UriComponentsBuilder.fromHttpUrl(url).queryParams(params).build().toUri())
                .accept(MediaType.TEXT_PLAIN) // 发送端发送的数据类型
                .acceptCharset(StandardCharsets.UTF_8)
                .retrieve()
                .onStatus(HttpStatus::isError, clientResponse -> {
                    throw new WxApiException("微信服务接口调用异常, HTTP status code：" + clientResponse.rawStatusCode());
                })
                .bodyToMono(clazz);
    }

    public Mono<T> wxPost(String url, Object params, Class<T> clazz) {
        return wxApiWebClient.post()
                .uri(UriComponentsBuilder.fromPath(url).build().toUri())
                .accept(MediaType.APPLICATION_JSON) // 代表客户端希望接受的数据类型
                .acceptCharset(StandardCharsets.UTF_8)
                .contentType(MediaType.APPLICATION_JSON) // 发送端发送的数据类型
                .bodyValue(params) // 参数
                .retrieve()
                .bodyToMono(clazz);
    }
}
